from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple
import json

from app.core.logging import logger
from app.schemas.analysis import (ChatAnalysis, EmotionAnalysis, ToneAnalysis,
                                 TopicAnalysis, OptimizationSuggestion)
from app.core.config import settings
from app.services.nlp.model_mgt_client import model_mgt_client
from app.services.nlp.virtual_model import virtual_nlp_model


class ChatAnalyzer:
    """聊天内容分析服务"""
    
    def __init__(self):
        """初始化聊天分析服务"""
        logger.info("Initializing Chat Analyzer Service")
        self.use_llm = settings.USE_LLM_FOR_MESSAGE_OPTIMIZATION
    
    async def analyze_chat(
        self, 
        messages: List[Dict[str, Any]], 
        relationship_type: Optional[str] = None
    ) -> ChatAnalysis:
        """
        分析聊天内容
        
        Args:
            messages: 消息列表
            relationship_type: 关系类型
            
        Returns:
            ChatAnalysis: 聊天分析结果
        """
        try:
            if not messages:
                logger.warning("No messages to analyze")
                return self._get_empty_analysis()
            
            # 合并所有消息内容进行分析
            combined_text = " ".join([msg["content"] for msg in messages if msg.get("content")])
            
            # 情感分析
            emotion_result = await virtual_nlp_model.analyze_emotion(combined_text)
            emotion_analysis = EmotionAnalysis(
                positive=emotion_result["positive"],
                negative=emotion_result["negative"],
                neutral=emotion_result["neutral"],
                dominant_emotion=emotion_result["dominant_emotion"]
            )
            
            # 语气分析
            tone_result = await virtual_nlp_model.analyze_tone(combined_text)
            tone_analysis = ToneAnalysis(
                formal=tone_result["formal"],
                friendly=tone_result["friendly"],
                aggressive=tone_result["aggressive"],
                submissive=tone_result["submissive"],
                confident=tone_result["confident"],
                dominant_tone=tone_result["dominant_tone"]
            )
            
            # 主题分析
            topic_result = await virtual_nlp_model.analyze_topic(combined_text)
            topic_analysis = TopicAnalysis(
                topics=topic_result["topics"],
                main_topic=topic_result["main_topic"]
            )
            
            # 计算词数
            word_count = len(combined_text)
            
            # 计算平均回复时间
            avg_response_time = self._calculate_avg_response_time(messages)
            
            # 生成关系评估
            relationship_assessment = self._assess_relationship(messages, relationship_type, emotion_analysis, tone_analysis)
            
            # 生成目标达成度
            goal_achievement = self._calculate_goal_achievement(messages, emotion_analysis, tone_analysis)
            
            # 构建完整分析结果
            chat_analysis = ChatAnalysis(
                emotion=emotion_analysis,
                tone=tone_analysis,
                topic=topic_analysis,
                word_count=word_count,
                avg_response_time=avg_response_time,
                relationship_assessment=relationship_assessment,
                goal_achievement=goal_achievement
            )
            
            return chat_analysis
        
        except Exception as e:
            logger.error(f"分析聊天内容失败: {str(e)}")
            return self._get_empty_analysis()
    
    def _get_empty_analysis(self) -> ChatAnalysis:
        """
        获取空的分析结果
        
        Returns:
            ChatAnalysis: 空的分析结果
        """
        return ChatAnalysis(
            emotion=EmotionAnalysis(
                positive=0.0,
                negative=0.0,
                neutral=1.0,
                dominant_emotion="neutral"
            ),
            tone=ToneAnalysis(
                formal=0.0,
                friendly=0.0,
                aggressive=0.0,
                submissive=0.0,
                confident=0.0,
                dominant_tone="neutral"
            ),
            topic=TopicAnalysis(
                topics=[],
                main_topic="unknown"
            ),
            word_count=0,
            avg_response_time=None,
            relationship_assessment=None,
            goal_achievement=None
        )
    
    def _calculate_avg_response_time(self, messages: List[Dict[str, Any]]) -> Optional[float]:
        """
        计算平均回复时间
        
        Args:
            messages: 消息列表
            
        Returns:
            Optional[float]: 平均回复时间（秒）
        """
        if len(messages) < 2:
            return None
        
        response_times = []
        
        # 按照发送时间排序
        sorted_messages = sorted(
            messages, 
            key=lambda x: datetime.strptime(x["sent_at"], "%Y-%m-%d %H:%M:%S") 
                if isinstance(x["sent_at"], str) 
                else x["sent_at"]
        )
        
        for i in range(1, len(sorted_messages)):
            current_msg = sorted_messages[i]
            prev_msg = sorted_messages[i-1]
            
            # 只计算方向不同的消息之间的时间差（即一问一答）
            if current_msg.get("direction") != prev_msg.get("direction"):
                # 获取发送时间
                current_time = current_msg["sent_at"]
                prev_time = prev_msg["sent_at"]
                
                # 转换为datetime对象
                if isinstance(current_time, str):
                    current_time = datetime.strptime(current_time, "%Y-%m-%d %H:%M:%S")
                if isinstance(prev_time, str):
                    prev_time = datetime.strptime(prev_time, "%Y-%m-%d %H:%M:%S")
                
                # 计算时间差（秒）
                time_diff = (current_time - prev_time).total_seconds()
                
                # 过滤掉超过1小时的回复，认为是不连续的对话
                if 0 < time_diff < 3600:
                    response_times.append(time_diff)
        
        if not response_times:
            return None
        
        return sum(response_times) / len(response_times)
    
    def _assess_relationship(
        self, 
        messages: List[Dict[str, Any]], 
        relationship_type: Optional[str],
        emotion_analysis: EmotionAnalysis,
        tone_analysis: ToneAnalysis
    ) -> str:
        """
        评估关系状况
        
        Args:
            messages: 消息列表
            relationship_type: 关系类型
            emotion_analysis: 情感分析结果
            tone_analysis: 语气分析结果
            
        Returns:
            str: 关系评估描述
        """
        if not relationship_type:
            relationship_type = "未指定"
        
        # 计算积极情绪比例
        positive_ratio = emotion_analysis.positive / max(
            emotion_analysis.positive + emotion_analysis.negative, 0.001
        )
        
        # 计算友好度
        friendliness = tone_analysis.friendly - tone_analysis.aggressive
        
        # 根据不同关系类型，使用不同的评估标准
        if relationship_type in ["superior", "client"]:
            # 对于上级和客户，强调礼貌和专业
            if tone_analysis.formal > 0.6 and friendliness > 0:
                status = "良好"
                advice = "保持专业礼貌的沟通方式"
            elif tone_analysis.formal < 0.4:
                status = "需注意"
                advice = "建议增加正式礼貌用语"
            else:
                status = "一般"
                advice = "可适当增加专业性表达"
        
        elif relationship_type in ["friend", "family"]:
            # 对于朋友和家人，强调亲密和情感
            if positive_ratio > 0.7 and friendliness > 0.3:
                status = "融洽"
                advice = "继续保持亲切的交流方式"
            elif positive_ratio < 0.4:
                status = "需要改善"
                advice = "建议增加积极情感表达"
            else:
                status = "一般"
                advice = "可以分享更多积极的话题"
        
        else:
            # 默认评估
            if positive_ratio > 0.6 and friendliness > 0.2:
                status = "良好"
                advice = "保持当前的沟通风格"
            elif positive_ratio < 0.4 or friendliness < 0:
                status = "需要改善"
                advice = "建议调整语气，增加积极表达"
            else:
                status = "一般"
                advice = "可以尝试更友好的表达方式"
        
        return f"{relationship_type}关系状态: {status}。{advice}。"
    
    def _calculate_goal_achievement(
        self, 
        messages: List[Dict[str, Any]], 
        emotion_analysis: EmotionAnalysis,
        tone_analysis: ToneAnalysis
    ) -> float:
        """
        计算目标达成度
        
        Args:
            messages: 消息列表
            emotion_analysis: 情感分析结果
            tone_analysis: 语气分析结果
            
        Returns:
            float: 目标达成度 (0-1)
        """
        # 简单实现，基于情感和语气评分
        # 在实际应用中，应该根据具体的聊天目标进行更复杂的评估
        
        # 积极情绪权重
        positive_weight = 0.4
        positive_score = emotion_analysis.positive
        
        # 合适语气权重
        tone_weight = 0.4
        tone_score = (tone_analysis.friendly + tone_analysis.confident) / 2
        
        # 互动质量权重
        interaction_weight = 0.2
        
        # 评估互动质量
        interaction_score = 0.5  # 默认中等
        if len(messages) > 5:
            # 消息数量充足，提高评分
            interaction_score = 0.7
        if len(messages) > 10:
            # 消息数量很多，进一步提高评分
            interaction_score = 0.9
        
        # 计算加权总分
        total_score = (
            positive_weight * positive_score +
            tone_weight * tone_score +
            interaction_weight * interaction_score
        )
        
        return total_score
    
    async def generate_suggestions(
        self, 
        text: str, 
        relationship_type: str,
        chat_goal: str,
        context_messages: Optional[List[Dict[str, Any]]] = None,
        user_prompt: Optional[str] = None
    ) -> List[OptimizationSuggestion]:
        """
        生成优化建议
        
        Args:
            text: 待优化文本
            relationship_type: 关系类型
            chat_goal: 聊天目标
            context_messages: 上下文消息列表
            user_prompt: 用户自定义提示
            
        Returns:
            List[OptimizationSuggestion]: 优化建议列表
        """
        try:
            # 判断是否使用大语言模型
            if self.use_llm:
                try:
                    # 使用model_mgt大语言模型生成优化建议
                    llm_suggestions = await self._generate_suggestions_with_llm(
                        text, relationship_type, chat_goal, context_messages, user_prompt
                    )
                    
                    logger.info(f"使用大语言模型生成优化建议成功: {len(llm_suggestions)}条建议")
                    return llm_suggestions
                    
                except Exception as e:
                    logger.error(f"大语言模型生成优化建议失败，将使用虚拟模型: {str(e)}")
                    # 如果LLM生成失败，回退到虚拟模型
                    return await self._generate_suggestions_with_virtual_model(
                        text, relationship_type, chat_goal, context_messages, user_prompt
                    )
            else:
                # 使用虚拟模型
                return await self._generate_suggestions_with_virtual_model(
                    text, relationship_type, chat_goal, context_messages, user_prompt
                )
            
        except Exception as e:
            logger.error(f"生成优化建议失败: {str(e)}")
            return []
    
    async def _generate_suggestions_with_llm(
        self, 
        text: str, 
        relationship_type: str,
        chat_goal: str,
        context_messages: Optional[List[Dict[str, Any]]] = None,
        user_prompt: Optional[str] = None
    ) -> List[OptimizationSuggestion]:
        """
        使用大语言模型生成优化建议
        
        Args:
            text: 待优化文本
            relationship_type: 关系类型
            chat_goal: 聊天目标
            context_messages: 上下文消息列表
            user_prompt: 用户自定义提示
            
        Returns:
            List[OptimizationSuggestion]: 优化建议列表
        """
        # 构建系统提示词
        system_prompt = """你是一个专业的聊天优化助手，负责提供对用户消息的改进建议，使其更适合特定关系和目标。

请根据提供的文本、关系类型和聊天目标，生成3条优化建议。每条建议应包含以下内容：
1. 优化后的文本
2. 优化的解释
3. 修改点详情（添加、删除或替换）
4. 预期效果（清晰度、礼貌度、有效性和情感影响）
5. 建议的置信度（0.0-1.0）

不同关系类型可能需要不同的沟通风格：
- 朋友关系：友好、随意、表达情感
- 同事关系：专业、尊重、有适当的距离
- 上下级关系：尊重、清晰、专业
- 家人关系：亲密、关心、支持
- 客户关系：专业、服务导向、礼貌

不同聊天目标也需要不同的沟通方式：
- 社交聊天：友好、轻松、建立联系
- 工作汇报：清晰、简洁、结构化
- 解决问题：明确、具体、提供方案
- 情感支持：共情、关心、安慰
- 协商事务：公平、灵活、寻求共识

请以JSON格式返回3条建议，每条包含以下字段：
- suggested_text：建议的修改后文本
- explanation：为什么这样修改
- modification_points：修改点列表，每个点包含type（添加/删除/替换）、position（开始/中间/结束）、original（原文）、suggested（建议）和reason（原因）
- expected_effect：预期效果，包含clarity、politeness、effectiveness和emotional_impact的评分（0.0-1.0）
- confidence：建议的置信度（0.0-1.0）

保持原始文本的核心意思，但使其更适合指定的关系和目标。"""

        # 如果有用户自定义提示，添加到系统提示中
        if user_prompt:
            system_prompt += f"\n\n用户特别要求的优化方向: {user_prompt}\n请特别注意用户的自定义提示，优先按照用户的提示方向进行优化。"

        # 构建用户提示词
        user_prompt_text = f"""请为以下文本提供优化建议：

文本：{text}
关系类型：{relationship_type}
聊天目标：{chat_goal}
"""

        # 如果有上下文消息，添加到提示词中
        if context_messages and len(context_messages) > 0:
            context_str = "上下文消息：\n"
            for i, msg in enumerate(context_messages):
                direction = "我" if msg.get("direction") == "outgoing" else "对方"
                context_str += f"{direction}: {msg.get('content', '')}\n"
            user_prompt_text += f"\n{context_str}"

        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt_text}
        ]
        
        try:
            # 调用大语言模型
            response = await model_mgt_client.chat_completion(
                messages=messages,
                temperature=0.7,
                max_tokens=1500
            )
            
            # 检查是否有错误
            if response.get("error"):
                logger.error(f"消息优化失败: {response.get('message')}")
                return []
                
            # 提取结果
            assistant_message = response.get("choices", [{}])[0].get("message", {}).get("content", "")
            
            # 解析JSON响应
            try:
                # 查找JSON内容的开始和结束
                json_start = assistant_message.find("[")
                json_end = assistant_message.rfind("]")
                
                if json_start >= 0 and json_end > json_start:
                    json_content = assistant_message[json_start:json_end+1]
                    suggestions_data = json.loads(json_content)
                    
                    # 转换为OptimizationSuggestion对象
                    suggestions = []
                    for suggestion_data in suggestions_data:
                        suggestion = OptimizationSuggestion(
                            original_text=text,
                            suggested_text=suggestion_data.get("suggested_text", text),
                            explanation=suggestion_data.get("explanation", ""),
                            modification_points=suggestion_data.get("modification_points", []),
                            expected_effect=suggestion_data.get("expected_effect", {}),
                            confidence=suggestion_data.get("confidence", 0.7)
                        )
                        suggestions.append(suggestion)
                    
                    return suggestions
                else:
                    logger.warning(f"无法从响应中提取JSON: {assistant_message}")
                    return []
                    
            except json.JSONDecodeError:
                logger.error(f"无法解析JSON响应: {assistant_message}")
                return []
                
        except Exception as e:
            logger.error(f"调用大语言模型生成优化建议异常: {str(e)}")
            return []
    
    async def _generate_suggestions_with_virtual_model(
        self, 
        text: str, 
        relationship_type: str,
        chat_goal: str,
        context_messages: Optional[List[Dict[str, Any]]] = None,
        user_prompt: Optional[str] = None
    ) -> List[OptimizationSuggestion]:
        """
        使用虚拟NLP模型生成优化建议
        
        Args:
            text: 待优化文本
            relationship_type: 关系类型
            chat_goal: 聊天目标
            context_messages: 上下文消息列表
            user_prompt: 用户自定义提示
            
        Returns:
            List[OptimizationSuggestion]: 优化建议列表
        """
        # 调用NLP模型生成优化建议
        optimization_result = await virtual_nlp_model.generate_optimization(
            text, relationship_type, chat_goal, context_messages, user_prompt
        )
        
        # 转换为OptimizationSuggestion对象
        suggestions = []
        for suggestion_data in optimization_result["suggestions"]:
            suggestion = OptimizationSuggestion(
                original_text=suggestion_data["original_text"],
                suggested_text=suggestion_data["suggested_text"],
                explanation=suggestion_data["explanation"],
                modification_points=suggestion_data["modification_points"],
                expected_effect=suggestion_data["expected_effect"],
                confidence=suggestion_data["confidence"]
            )
            suggestions.append(suggestion)
        
        return suggestions


# 创建单例实例
chat_analyzer = ChatAnalyzer()